package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.pojos.CommentSaveDto;
import com.heima.comment.pojos.CommentVo;
import com.heima.comment.service.ApCommentService;
import com.heima.common.constants.ApCommentConstants;
import com.heima.feign.article.IArticleClient;
import com.heima.feign.user.IUserClient;
import com.heima.feign.wemedia.IWemediaClient;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.ApUserThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Zqr
 */
@Service
public class ApCommentServiceImpl implements ApCommentService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private IWemediaClient iWemediaClient;
    @Autowired
    private IUserClient iUserClient;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //1.入参校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断用户是否登录
        ApUser apUser = ApUserThreadLocalUtil.getUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //远程feign调用获取当前登录用户的详细信息
        apUser = iUserClient.findUserById(apUser.getId());
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "当前登录用户信息有误!");
        }

        //3.判断当前文章是否可评论
        //fegin远程调用获取文章的配置信息.
        ResponseResult resultRes = iArticleClient.findConfig(dto.getArticleId());
        if (resultRes.getCode() == 200) {
            ApArticleConfig apArticleConfig =
                    JSON.parseObject(JSON.toJSONString(resultRes.getData()), ApArticleConfig.class);
            if (!apArticleConfig.getIsComment()) {
                //当前文章不可评论
                return ResponseResult.errorResult(AppHttpCodeEnum.ARTICLE_REFUSE_COMMENT);
            }
        }
        //4.评论内容不可以超过140个字
        if (dto.getContent().length() >= 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论内容不可以超过104个字!");
        }
        //5.审核评论内容
        Boolean isOK = iWemediaClient.isTextScanOk(dto.getContent());
        if (!isOK) {
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_COMMENT_TEXT_SCAN_FAIL, "评论包含非法内容!");
        }


        //6.将评论数据保存到MongoDB
        ApComment apComment = new CommentVo();
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setEntryId(dto.getArticleId());
        apComment.setType((short) 0);
        apComment.setContent(dto.getContent());
        apComment.setLikes(0);//评论点赞数初始为0
        apComment.setFlag((short) 0);
        apComment.setReply(0);
        apComment.setCreatedTime(new Date());
        mongoTemplate.save(apComment, "ap_comment");

        //发送kafka用于更新文章微服务中ap_article表中的comment(评论数量) / TODO ? wm_news_statistics表中的comment(评论量)
        Map map = new HashMap();
        map.put("articleId", dto.getArticleId());
        map.put("apUserId", apUser.getId());
        map.put("add", 1);
        kafkaTemplate.send(ApCommentConstants.AP_COMMENT_SYNC_ARTICLE, JSON.toJSONString(map));


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    /**
     * 查询评论列表
     *
     * @param dto
     * @return 返回为CommentVo
     */
    @Override
    public ResponseResult loadComment(CommentDto dto) {
        //1.入参校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断用户是否登录
        ApUser apUser = ApUserThreadLocalUtil.getUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

//TODO 根据创建时间倒序   分页条件最小时间
        List<CommentVo> commentVoList = mongoTemplate.find(Query.query(
                        Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Order.desc("createdTime")))
                .limit(10).skip((dto.getIndex() - 1) * 10), CommentVo.class);

        commentVoList = commentVoList.stream().map(e -> {
            ApCommentLike commentLike = mongoTemplate.findOne(Query.query(Criteria.where("commentId").is(e.getId())
                    .and("authorId").is(apUser.getId())), ApCommentLike.class);
            if (commentLike != null) {
                e.setOperation((short) 0);
            }
            return e;
        }).collect(Collectors.toList());
        //3.响应数据
        return ResponseResult.okResult(commentVoList);
    }
}
